
using System;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design;
using Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration.Design.MatchingRules;
using Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration.Design.Properties;
using Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration.Design;
using EntLibContrib.PolicyInjection.Design.Nodes;

namespace EntLibContrib.PolicyInjection.Design
{
	internal class PolicyInjectionCommandRegistrar : CommandRegistrar
	{
        public PolicyInjectionCommandRegistrar(IServiceProvider serviceProvider)
			: base(serviceProvider)
		{ }

		public override void Register()
		{
            AddDefaultCommands(typeof(NotMatchingRuleNode));
            AddDefaultCommands(typeof(OrMatchingRuleNode));
            AddDefaultCommands(typeof(AndMatchingRuleNode));
            AddDefaultCommands(typeof(CursorCallHandlerNode));
            AddDefaultCommands(typeof(OneWayCallHandlerNode));
            AddDefaultCommands(typeof(SynchronizedCallHandlerNode));
            AddDefaultCommands(typeof(ThreadSafeCallHandlerNode));
            AddDefaultCommands(typeof(TransactionScopeCallHandlerNode));

            AddOrMatchingRuleCommands(typeof(MatchingRuleCollectionNode), NodeMultiplicity.Allow);
            AddNotMatchingRuleCommands(typeof(MatchingRuleCollectionNode), NodeMultiplicity.Allow);
            AddAndMatchingRuleCommands(typeof(MatchingRuleCollectionNode), NodeMultiplicity.Allow);

            AddAllMatchingRuleCommands(typeof(AndMatchingRuleNode), NodeMultiplicity.Allow);
            AddAllMatchingRuleCommands(typeof(OrMatchingRuleNode), NodeMultiplicity.Allow);
            AddAllMatchingRuleCommands(typeof(NotMatchingRuleNode), NodeMultiplicity.Disallow);

            AddMoveUpDownCommands(typeof(CursorCallHandlerNode));
            AddMoveUpDownCommands(typeof(OneWayCallHandlerNode));
            AddMoveUpDownCommands(typeof(SynchronizedCallHandlerNode));
            AddMoveUpDownCommands(typeof(ThreadSafeCallHandlerNode));
            AddMoveUpDownCommands(typeof(TransactionScopeCallHandlerNode));

            AddMultipleChildNodeCommand(Resources.AddCursorCallHandlerCommandText,
                Resources.AddCursorCallHandlerCommandTextLong,
                typeof(CursorCallHandlerNode),
                typeof(CallHandlersCollectionNode));

            AddMultipleChildNodeCommand(Resources.AddOneWayCallHandlerCommandText,
                Resources.AddOneWayCallHandlerCommandTextLong,
                typeof(OneWayCallHandlerNode),
                typeof(CallHandlersCollectionNode));

            AddMultipleChildNodeCommand(Resources.AddSynchronizedCallHandlerCommandText,
                Resources.AddSynchronizedCallHandlerCommandTextLong,
                typeof(SynchronizedCallHandlerNode),
                typeof(CallHandlersCollectionNode));

            AddMultipleChildNodeCommand(Resources.AddThreadSafeCallHandlerCommandText,
                Resources.AddThreadSafeCallHandlerCommandTextLong,
                typeof(ThreadSafeCallHandlerNode),
                typeof(CallHandlersCollectionNode));

            AddMultipleChildNodeCommand(Resources.AddTransactionScopeCallHandlerCommandText,
                Resources.AddTransactionScopeCallHandlerCommandTextLong,
                typeof(TransactionScopeCallHandlerNode),
                typeof(CallHandlersCollectionNode));
        }

        private void AddAllMatchingRuleCommands(Type registerType, NodeMultiplicity multiplicity)
        {

            AddOrMatchingRuleCommands(registerType, multiplicity);

            AddNotMatchingRuleCommands(registerType, multiplicity);

            AddAndMatchingRuleCommands(registerType, multiplicity);

            AddAssemblyMatchingRuleCommands(registerType, multiplicity);

            AddCustomAttributeMatchingRuleCommands(registerType, multiplicity);

            AddCustomMatchingRuleCommands(registerType, multiplicity);

            AddMemberNameMatchingRuleCommands(registerType, multiplicity);

            AddMethodSignatureMatchingRuleCommands(registerType, multiplicity);

            AddNamespaceMatchingRuleCommands(registerType, multiplicity);

            AddParameterTypeMatchingRuleCommands(registerType, multiplicity);

            AddPropertyMatchingRuleCommands(registerType, multiplicity);

            AddReturnTypeMatchingRuleCommands(registerType, multiplicity);

            AddTagAttributeMatchingRuleCommands(registerType, multiplicity);

            AddTypeMatchingRuleCommands(registerType, multiplicity);
        }


        private void AddNotMatchingRuleCommands(Type registerType, NodeMultiplicity multiplicity)
        {
            AddChildNodeCommand(Resources.NotMatchingRuleCommandText,
                Resources.NotMatchingRuleCommandTextLong,
                typeof(NotMatchingRuleNode), (multiplicity == NodeMultiplicity.Allow) ? typeof(NotMatchingRuleNode) : typeof(MatchingRuleNode), registerType, multiplicity);
        }
        private void AddOrMatchingRuleCommands(Type registerType, NodeMultiplicity multiplicity)
        {
            AddChildNodeCommand(Resources.OrMatchingRuleCommandText,
                Resources.OrMatchingRuleCommandTextLong,
                typeof(OrMatchingRuleNode), (multiplicity == NodeMultiplicity.Allow) ? typeof(OrMatchingRuleNode) : typeof(MatchingRuleNode), registerType, multiplicity);
        }
        private void AddAndMatchingRuleCommands(Type registerType, NodeMultiplicity multiplicity)
        {
            AddChildNodeCommand(Resources.AndMatchingRuleCommandText,
                Resources.AndMatchingRuleCommandTextLong,
                typeof(AndMatchingRuleNode), (multiplicity == NodeMultiplicity.Allow) ? typeof(AndMatchingRuleNode) : typeof(MatchingRuleNode), registerType, multiplicity);
        }

		private void AddTagAttributeMatchingRuleCommands(Type registerType, NodeMultiplicity multiplicity)
		{
			AddChildNodeCommand(Resources.TagAttributeMatchingRuleCommandText,
				Resources.TagAttributeMatchingRuleCommandTextLong,
                typeof(TagAttributeMatchingRuleNode), (multiplicity == NodeMultiplicity.Allow) ? typeof(TagAttributeMatchingRuleNode) : typeof(MatchingRuleNode), registerType, multiplicity);
		}

        private void AddTypeMatchingRuleCommands(Type registerType, NodeMultiplicity multiplicity)
		{
            AddChildNodeCommand(Resources.AddTypeMatchingRuleCommandText,
				Resources.AddTypeMatchingRuleTextLong,
                typeof(TypeMatchingRuleNode), (multiplicity == NodeMultiplicity.Allow) ? typeof(TypeMatchingRuleNode) : typeof(MatchingRuleNode), registerType, multiplicity);
		}

        private void AddReturnTypeMatchingRuleCommands(Type registerType, NodeMultiplicity multiplicity)
		{
            AddChildNodeCommand(Resources.AddReturnTypeMatchingRuleCommandText,
				Resources.AddReturnTypeMatchingRuleCommandTextLong,
                typeof(ReturnTypeMatchingRuleNode), (multiplicity == NodeMultiplicity.Allow) ? typeof(ReturnTypeMatchingRuleNode) : typeof(MatchingRuleNode), registerType, multiplicity);
		}

        private void AddPropertyMatchingRuleCommands(Type registerType, NodeMultiplicity multiplicity)
		{
            AddChildNodeCommand(Resources.AddPropertyMatchingRuleCommandText,
				Resources.AddPropertyMatchingRuleCommandTextLong,
                typeof(PropertyMatchingRuleNode), (multiplicity == NodeMultiplicity.Allow) ? typeof(PropertyMatchingRuleNode) : typeof(MatchingRuleNode), registerType, multiplicity);
		}

        private void AddMethodSignatureMatchingRuleCommands(Type registerType, NodeMultiplicity multiplicity)
		{
            AddChildNodeCommand(Resources.AddMethodSignatureMatchingRuleCommandText,
				Resources.AddMethodSignatureMatchingRuleCommandTextLong,
                typeof(MethodSignatureMatchingRuleNode), (multiplicity == NodeMultiplicity.Allow) ? typeof(MethodSignatureMatchingRuleNode) : typeof(MatchingRuleNode), registerType, multiplicity);
		}

        private void AddNamespaceMatchingRuleCommands(Type registerType, NodeMultiplicity multiplicity)
		{
            AddChildNodeCommand(Resources.AddNamespaceMatchingRuleCommandText,
				Resources.AddNamespaceMatchingRuleCommandTextLong,
                typeof(NamespaceMatchingRuleNode), (multiplicity == NodeMultiplicity.Allow) ? typeof(NamespaceMatchingRuleNode) : typeof(MatchingRuleNode), registerType, multiplicity);
		}

        private void AddMemberNameMatchingRuleCommands(Type registerType, NodeMultiplicity multiplicity)
		{
            AddChildNodeCommand(Resources.AddMemberNameMatchingRuleCommandText,
				Resources.AddMemberNameMatchingRuleCommandTextLong,
                typeof(MemberNameMatchingRuleNode), (multiplicity == NodeMultiplicity.Allow) ? typeof(MemberNameMatchingRuleNode) : typeof(MatchingRuleNode), registerType, multiplicity);
		}

        private void AddCustomMatchingRuleCommands(Type registerType, NodeMultiplicity multiplicity)
		{
            AddChildNodeCommand(Resources.AddCustomMatchingRuleCommandText,
				Resources.AddCustomMatchingRuleCommandTextLong,
                typeof(CustomMatchingRuleNode), (multiplicity == NodeMultiplicity.Allow) ? typeof(CustomMatchingRuleNode) : typeof(MatchingRuleNode), registerType, multiplicity);
		}

        private void AddCustomAttributeMatchingRuleCommands(Type registerType, NodeMultiplicity multiplicity)
		{
            AddChildNodeCommand(Resources.AddCustomAttributeMatchingRuleCommandText,
				Resources.AddCustomAttributeMatchingRuleCommandTextLong,
                typeof(CustomAttributeMatchingRuleNode), (multiplicity == NodeMultiplicity.Allow) ? typeof(CustomAttributeMatchingRuleNode) : typeof(MatchingRuleNode), registerType, multiplicity);
		}

        private void AddAssemblyMatchingRuleCommands(Type registerType, NodeMultiplicity multiplicity)
		{
            AddChildNodeCommand(Resources.AddAssemblyMatchingRuleCommandText,
				Resources.AddAssemblyMatchingRuleCommandTextLong,
                typeof(AssemblyMatchingRuleNode), (multiplicity == NodeMultiplicity.Allow) ? typeof(AssemblyMatchingRuleNode) : typeof(MatchingRuleNode), registerType, multiplicity);
		}

        private void AddParameterTypeMatchingRuleCommands(Type registerType, NodeMultiplicity multiplicity)
		{
            AddChildNodeCommand(Resources.AddParameterTypeMatchingRuleCommandText,
				Resources.AddParameterTypeMatchingRuleCommandTextLong,
                typeof(ParameterTypeMatchingRuleNode), (multiplicity == NodeMultiplicity.Allow) ? typeof(ParameterTypeMatchingRuleNode) : typeof(MatchingRuleNode), registerType, multiplicity);
		}
	}
}